# coding=utf-8

from re import T

# 反转16进制数据
def hex_reversed(h):
    pass

def hex2string(h):
    # 需要清空空字节
    h = "00"+h[2:]
    step = 4
    b = [h[i:i+step] for i in range(0,len(h),step)]
    def mapFun(s):
        if s[0:2] == "00":
            return s[2:]
        else:
            return s

    return bytearray.fromhex("".join(map(mapFun, b))).decode()


# 把前面的0去掉
def hex2int(h):
    return int(h, 16)

class ParseXml():
    def __init__(self, byte_s) -> None:
        # print(byte_s)
        self.bytestr = byte_s
        self.step = 4

    # 截取byte
    def __parseByte(self, start, size) -> int:
        return int.from_bytes(self.bytestr[start:(start+size)], "little")

    # 解析头部
    def parseHeader(self):
        self.Header = {
            "magicnumber":self.__parseByte(0, self.step),
            "filesize": self.__parseByte(4, self.step)
        }
    
    # 解析StringChunk
    def parseStringChunk(self):
        self.StringChunk = {
            "scSignature": self.__parseByte(8, self.step),
            "scSize": self.__parseByte(0xc, self.step),
            "scStringCount": self.__parseByte(0x10, self.step),
            "scStyleCount": self.__parseByte(0x14, self.step),
            "scUNKNOWN": self.__parseByte(0x18, self.step),
            "scStringPoolOffset": self.__parseByte(0x1c, self.step),
            "scStylePoolOffset": self.__parseByte(0x20, self.step)
        }
    
    # 解析每个字符串的相对偏移量
    def parseStringOffsets(self):
        sign = 0x20 + self.step
        res_list = []
        sf_size = self.StringChunk["scStringCount"]
        for i in range(sf_size):
            res_list.append(self.__parseByte(sign, self.step))
            sign = sign+self.step
        self.StringOffsets = res_list
    
    # 解析字符串
    def parseString(self) -> list:
        sign = 0x20 + self.step + (self.StringChunk["scStringCount"]*4)
        res_list = []
        string_items = self.StringOffsets
        
        for i in range(len(string_items) -1):
            start = sign+string_items[i]
            size = sign+string_items[i+1] - start
            # 临时hex数据
            temp_hex = hex(self.__parseByte(start, size))
            # 获取字符串长度
            s_len = hex2int(temp_hex[-4:])
            s_content = hex2string(temp_hex[0:-4])[::-1]
            if len(s_content) == s_len:
                res_list.append(s_content)
            else:
                assert 0, f"获取到的字符串长度错误{s_len} != {len(s_content)} -- {s_content}"

        return res_list
    
    def run(self) -> None:
        self.parseHeader()
        self.parseStringChunk()
        self.parseStringOffsets()
        r = self.parseString()
        print(r)
        # 解析字符串
    

def exec() -> None:
    with open(file="AndroidManifest.xml", mode="rb") as f:
        byte_s = f.read()
        p = ParseXml(byte_s)
        p.run()

if __name__ == "__main__":
    exec()

